package com.ruoyi.framework.aspectj;

import com.ruoyi.common.annotation.ExcelField;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.exception.BusinessException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.sun.org.apache.xpath.internal.operations.Bool;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.swing.text.StyledEditorKit;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Excel 导入统一拦截处理,【方法弃用】
 */
public class ExcelImportAspect {

    protected Logger logger = LoggerFactory.getLogger(getClass());


    // 配置织入点
    @Pointcut("@annotation(com.ruoyi.common.annotation.ExcelImportAdvice)")
    public void dataExcelImportCut() {
    }

    @Before("dataExcelImportCut()")
    public void doBefore(JoinPoint point) {
        Object[] args = point.getArgs();
        // 导入数据集合
        List<Object> dataList = (List<Object>) args[0];
        if (dataList.size() > 1) {
            handleBusiness(dataList);
        } else {
            throw new BusinessException("模板的数据不能为空,提示【请不要删除第一行示例数据】!");
        }
    }

    /**
     * 业务处理
     *
     * @param dataList
     */
    private void handleBusiness(List<Object> dataList) {
        // 存储需要必填的方法
        Map<Method, ExcelField> methodMap = new HashMap<>();
        // TODO 错误消息记录
        StringBuilder message = new StringBuilder();
        Class<?> entityClass = dataList.get(0).getClass();
        Method[] declaredMethods = entityClass.getDeclaredMethods();
        // 方法遍历，获取包含ExcelField注解的方法
        for (int i = 0; i < declaredMethods.length; i++) {
            ExcelField annotation = declaredMethods[i].getAnnotation(ExcelField.class);
            // 注解不为空
            if (annotation != null) {
                //  保存必填信息
                methodMap.put(declaredMethods[i], annotation);
            }
        }
        // 数据必填监测
        for (int j = 1, end = dataList.size(); j < end; j++) {
            Object entity = dataList.get(j);
            // 表头信息占用两行
            int rowIndex = j + 2;
            methodMap.forEach((key, fieldVal) -> {
                try {
                    // 获取数据值
                    Object invokeVal = key.invoke(entity);
                    // 必填
                    if (fieldVal.required() == ExcelField.ExcelRequired.must) {
                        if (isNullOrEmpty(invokeVal)) {
                            message.append("第 " + rowIndex + " 行,列名称【" + fieldVal.filedName() + "】为【必填项】请检查模板内容!</br>");
                        } else {
                            // TODO 此处关闭校验
                            //validateFieldVal(invokeVal, key.getReturnType(), rowIndex, fieldVal.filedName(), message);
                        }
                    } else {
                        // 数据有值
                        if (!isNullOrEmpty(invokeVal)) {
                            // 校验类型是否正确
                            // TODO 此处关闭校验
                            // validateFieldVal(invokeVal, key.getReturnType(), rowIndex, fieldVal.filedName(), message);
                        }
                    }
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                    logger.error(e.getMessage());
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                    logger.error(e.getMessage());
                }
            });
        }

        if (message.length() > 0) {
            message.insert(0, "很抱歉，导入失败！在Excel中检测到一些问题未能通过验证，校验信息如下：");
            throw new BusinessException(message.toString());
        }
    }

    /**
     * 判断是否为空
     *
     * @param object
     * @return
     */
    private boolean isNullOrEmpty(Object object) {
        boolean result = true;
        if (object != null && StringUtils.isNotEmpty(object.toString())) {
            result = false;
        }
        return result;
    }

    /**
     * Excel导入类型校验
     *
     * @param val
     * @param validateType
     * @param rowIndex
     * @param fieldName
     * @param message
     */
    private void validateFieldVal(Object val, Class validateType, int rowIndex, String fieldName, StringBuilder message) {
        // 整数类型判断
        if (int.class == validateType || Integer.TYPE == validateType || Integer.class == validateType) {
            if (Convert.toInt(val) == null) {
                message.append("发现类型错误：第 " + rowIndex + " 行,列名称【" + fieldName + "】应输入数字!");
            }
            // 单精度浮点型判断
        } else if (float.class == validateType || Float.TYPE == validateType || Float.class == validateType) {
            if (Convert.toFloat(val) == null) {
                message.append("发现类型错误：第 " + rowIndex + " 行,列名称【" + fieldName + "】应输入数字!");
            }
            // 双精度判断
        } else if (double.class == validateType || Double.TYPE == validateType || Double.class == validateType) {
            if (Convert.toDouble(val) == null) {
                message.append("发现类型错误：第 " + rowIndex + " 行,列名称【" + fieldName + "】应输入数字!");
            }
            // 长整型判断
        } else if (long.class == validateType || Long.TYPE == validateType || Long.class == validateType) {
            if (Convert.toLong(val) == null) {
                message.append("发现类型错误：第 " + rowIndex + " 行,列名称【" + fieldName + "】应输入数字!");
            }
            // 短整型
        } else if (short.class == validateType || Short.TYPE == validateType || Short.class == validateType) {
            if (Convert.toShort(val) == null) {
                message.append("发现类型错误：第 " + rowIndex + " 行,列名称【" + fieldName + "】应输入数字!");
            }
            // 日期类型
        } else if (Date.class == validateType) {
            if (val instanceof String && DateUtils.parseDate(val) == null) {
                message.append("发现类型错误：第 " + rowIndex + " 行,列名称【" + fieldName + "】应输入日期格式或者时间戳!");
            }
            // 数字类型
        } else if (BigDecimal.class == validateType) {
            if (Convert.toBigDecimal(val) == null) {
                message.append("发现类型错误：第 " + rowIndex + " 行,列名称【" + fieldName + "】应输入数字!");
            }
        }
    }
}
